package com.inspinia.upms.rpc.service;

import com.inspinia.base.dao.BaseDao;
import com.inspinia.base.service.BaseServiceImpl;
import com.inspinia.base.util.CollectionUtil;
import com.inspinia.upms.common.model.dept.UpmsDept;
import com.inspinia.upms.common.model.org.UpmsOrgDeptVo;
import com.inspinia.upms.common.model.org.UpmsOrgDeptVoType;
import com.inspinia.upms.common.model.org.UpmsOrganization;
import com.inspinia.upms.common.model.post.UpmsPost;
import com.inspinia.upms.dao.UpmsOrganizationDao;
import com.inspinia.upms.rpc.api.UpmsDeptService;
import com.inspinia.upms.rpc.api.UpmsOrganizationService;
import com.inspinia.upms.rpc.api.UpmsPostService;
import com.inspinia.upms.rpc.api.UpmsUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static com.inspinia.upms.common.model.org.UpmsOrgDeptVoType.dept;

/**
 *
 * @author veblen
 * @date 16-2-1
 */
@Service
public class UpmsOrganizationServiceImpl extends BaseServiceImpl<UpmsOrganization> implements UpmsOrganizationService {
    @Autowired
    private UpmsOrganizationDao upmsOrganizationDao;
    @Autowired
    private UpmsDeptService upmsDeptService;
    @Autowired
    private UpmsUserService upmsUserService;
    @Autowired
    private UpmsPostService upmsPostService;

    public static final int MAX_WEIGHTS = 100;

    @Override
    protected BaseDao<UpmsOrganization> getDao() {
        return upmsOrganizationDao;
    }

    @Override
    @Transactional
    public boolean insertByBean(UpmsOrganization bean) {
        boolean bl = validate(bean);
        if (!bl) {
            UpmsOrganization parent = get(bean.getPid());
            if (parent != null) {
                bean.setSeq(parent.getSeq() + 1);
                if (parent.getSeq() != 0 && parent.getProvinceId() != null){
                    bean.setProvinceId(parent.getProvinceId());
                }
                if (Objects.nonNull(bean.getCountyId())){
                    bean.setCityId(parent.getCityId());
                }
            }
            super.insert(bean);
            bl = true;
        } else {
            bl = false;
        }
        return bl;
    }

    private boolean validate(UpmsOrganization bean) {
        return validateName(bean.getName(), bean.getId(), bean.getPid());
    }

    @Override
    @Transactional
    public boolean updateByBean(UpmsOrganization bean) {
        boolean bl = validate(bean);
        if (!bl) {
            super.update(bean);
            bl = true;
        } else {
            bl = false;
        }
        return bl;
    }

    @Override
    public List<UpmsOrganization> findAll() {
        return upmsOrganizationDao.findAll();
    }

    @Override
    public boolean validateName(String resourceName, Long resourceId, Long pid) {
        return upmsOrganizationDao.countByName(resourceName, resourceId, pid) > 0;
    }

    @Override
    public List<Long> findChildrenIds(Long id) {
        return upmsOrganizationDao.findChildrenIds(id);
    }

    @Override
    public void findChildrenById(Long id, List<Long> ids) {
        List<Long> list = findChildrenIds(id);
        ids.addAll(list);
        if (list.size() != 0) {
            for (int i = 0; i < list.size(); i++) {
                findChildrenById(list.get(i), ids);
            }
        }

    }

    @Override
    public List<UpmsOrgDeptVo> findOrgAndDept4tree(UpmsOrgDeptVoType treeType) {

        //先查找出所有的组织和部门信息。
        List<UpmsOrgDeptVo> orgDeptVos;
        switch (treeType) {
            case org:
                List<UpmsOrganization> orgs = findAll();
                orgDeptVos = new ArrayList<>(orgs.size());
                //组装树形数据
                for (UpmsOrganization org : orgs) {
                    UpmsOrgDeptVo orgDeptVo = new UpmsOrgDeptVo(org.getId(), org.getName(), UpmsOrgDeptVoType.org, org.getPid());
                    orgDeptVos.add(orgDeptVo);
                }
                break;
            case post:
                //先拼接部门的组织的树
                orgDeptVos = findOrgAndDept4tree(dept);
                List<UpmsPost> posts = upmsPostService.findAll();
                for (UpmsPost post : posts) {
                    UpmsOrgDeptVo orgDeptVo = new UpmsOrgDeptVo(post.getId(), post.getPostName(), UpmsOrgDeptVoType.post, post.getDeptId());
                    orgDeptVos.add(orgDeptVo);
                }
                break;
            default:
                //默认使用部门的树
                List<UpmsDept> departments = upmsDeptService.findAll();
                orgDeptVos = findOrgAndDept4tree(UpmsOrgDeptVoType.org);
                for (UpmsDept dept : departments) {
                    UpmsOrgDeptVo orgDeptVo = new UpmsOrgDeptVo(dept.getId(), dept.getDeptName(), UpmsOrgDeptVoType.dept, dept.getOrgId());
                    orgDeptVos.add(orgDeptVo);
                }
                break;
        }

        return orgDeptVos;
    }

    @Override
    public String getNameById(Long orgId) {
        return upmsOrganizationDao.getNameById(orgId);
    }

    @Override
    public List<Long> findOrgIdByCityId(Long cityId) {
        return upmsOrganizationDao.findOrgIdByCityId(cityId);
    }

    @Override
    public List<Long> findOrgIdByCountyId(Long countyId) {
        return upmsOrganizationDao.findOrgIdByCountyId(countyId);
    }

    @Override
    public List<Long> findCityIds(List<Long> orgIds) {
        if (CollectionUtil.isNotEmpty(orgIds)) {
            return upmsOrganizationDao.findCityIds(orgIds);
        }
        return null;
    }

    @Override
    public List<Long> findOrgIdsByNames(List<String> orgName) {
        if (CollectionUtil.isNotEmpty(orgName)) {
            return upmsOrganizationDao.findOrgIdsByNames(orgName);
        }
        return null;
    }

    @Override
    public List<UpmsOrganization> findAllWithExcludeIds(Long... excludeIds) {
        return upmsOrganizationDao.findAllWithExcludeIds(excludeIds);
    }

    @Override
    public List<Long> findOrgIdByDeptIds(List<Long> deptIds) {
        if (CollectionUtil.isNotEmpty(deptIds)) {
            return upmsOrganizationDao.findOrgIdByDeptIds(deptIds);
        }
        return null;
    }

    @Override
    public UpmsOrganization findOrgByUserId(Long userId) {
        List<UpmsDept> departmentList = upmsDeptService.findByUserId(userId);
        if (departmentList != null && departmentList.size() > 0) {
            Long orgId = upmsDeptService.getOrgId(departmentList.get(0).getId());
            return get(orgId);
        }
        return null;
    }


    @Override
    @Transactional
    public int delete(Long id) {
        List<Long> ids = new ArrayList<>();
        findChildrenById(id, ids);
        ids.add(id);
        upmsOrganizationDao.batchDelete(ids);
        return 1;
    }

    @Override
    public List<UpmsOrganization> findOrganizationByArea(Long provinceId, Long cityId, Long countyId) {
        return upmsOrganizationDao.findOrganizationByArea(provinceId, cityId, countyId);
    }

    @Override
    public List<UpmsOrganization> findByParentId(Long parentId) {
        return upmsOrganizationDao.findOrganizationByParentId(parentId);
    }

    @Override
    public UpmsOrganization getParentOrg(Long userId) {
        Long firstOrgId = findFirstOrgId(userId);
        if (firstOrgId != null) {
            return upmsOrganizationDao.getParentOrg(firstOrgId);
        }
        return null;

    }

    private Long findFirstOrgId(Long userId) {
        List<Long> orgIdsByUserId = upmsUserService.findOrgIdsByUserId(userId);
        if (CollectionUtil.isNotEmpty(orgIdsByUserId)) {
            return orgIdsByUserId.get(0);
        }
        return null;
    }

    @Override
    public List<UpmsOrganization> findSameLevelOrgs(Long userId) {
        Long firstOrgId = findFirstOrgId(userId);
        if (firstOrgId != null) {
            return upmsOrganizationDao.findSameLevelOrgs(firstOrgId);
        }
        return null;

    }

    @Override
    public List<UpmsOrganization> findSameLevelOrgAndCity(Long userId) {
        Long firstOrgId = findFirstOrgId(userId);
        if (firstOrgId != null) {
            return upmsOrganizationDao.findSameLevelOrgAndCity(firstOrgId);
        }
        return null;
    }
}
